import { HttpStatusCode, ErrorCode } from '../types/statusCodes';

export class AppError extends Error {
  public readonly statusCode: HttpStatusCode;
  public readonly errorCode: ErrorCode;
  public readonly details: any;
  public readonly isOperational: boolean;

  constructor(
    message: string,
    statusCode: HttpStatusCode = HttpStatusCode.INTERNAL_SERVER_ERROR,
    errorCode: ErrorCode = ErrorCode.UNKNOWN_ERROR,
    details?: any,
    isOperational: boolean = true
  ) {
    super(message);
    this.statusCode = statusCode;
    this.errorCode = errorCode;
    this.details = details;
    this.isOperational = isOperational;

    // 保持正确的堆栈跟踪
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, AppError);
    }
  }
}

// 常用错误类
export class ValidationError extends AppError {
  constructor(
    message: string = '参数验证失败', 
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.BAD_REQUEST, 
      ErrorCode.VALIDATION_ERROR, 
      details
    );
  }
}

export class NotFoundError extends AppError {
  constructor(
    message: string = '资源未找到',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.NOT_FOUND, 
      ErrorCode.RESOURCE_NOT_FOUND,
      details
    );
  }
}

export class UnauthorizedError extends AppError {
  constructor(
    message: string = '未授权访问',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.UNAUTHORIZED, 
      ErrorCode.ACCESS_DENIED,
      details
    );
  }
}

export class ForbiddenError extends AppError {
  constructor(
    message: string = '禁止访问',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.FORBIDDEN, 
      ErrorCode.ACCESS_DENIED,
      details
    );
  }
}

export class ConflictError extends AppError {
  constructor(
    message: string = '资源冲突',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.CONFLICT, 
      ErrorCode.USER_ALREADY_EXISTS,
      details
    );
  }
}

export class NotFoundSourceError extends AppError {
  constructor(
    message: string = '数据源不存在',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.NOT_FOUND, 
      ErrorCode.SOURCES_NOT_FOUND,
      details
    );
  }
}


export class SourceInitError extends AppError {
  constructor(
    message: string = '数据源初始化错误',
    details?: any
  ) {
    super(
      message, 
      HttpStatusCode.NOT_FOUND, 
      ErrorCode.SOURCES_INIT_ERROR,
      details
    );
  }
}